/** \file    bmpmorph.cpp
  * \brief   Bitmap morthological operations.
  * \date    2001 - 2005
  * \author  Fedor Chelnokov
  * \version $Header: /home/cscom1r4/cvsroot/cs/imglib/src/bmpmorph.cpp,v 1.3 2005/06/17 14:10:59 cscom1r4 Exp $
  */

#include "imglib/bmpmorph.h"

namespace img {

void erode4( bitmap &bmp, const bitmap &src )
{
	assert(bmp.data() != src.data());
	int w = src.width();
	int h = src.height();
	bmp = src;
	combine( bmp, 1, 0, w, h, src, 0, 0, bit_and() );
	combine( bmp, -1, 0, w, h, src, 0, 0, bit_and() );
	combine( bmp, 0, 1, w, h, src, 0, 0, bit_and() );
	combine( bmp, 0, -1, w, h, src, 0, 0, bit_and() );
}

void erode8( bitmap &bmp, const bitmap &src )
{
	assert(bmp.data() != src.data());
	int w = src.width();
	int h = src.height();
	bitmap tmp = src;
	combine( tmp,  1,  0, w, h, src, 0, 0, bit_and() );
	combine( tmp, -1,  0, w, h, src, 0, 0, bit_and() );
	bmp = tmp;
	combine( bmp,  0,  1, w, h, tmp, 0, 0, bit_and() );
	combine( bmp,  0, -1, w, h, tmp, 0, 0, bit_and() );
}

void erode4( bitmap &bmp, const bitmap &src, int iterations )
{
	assert( iterations>=1 );
	if( iterations == 1 ) {
		erode4( bmp, src );
		return;
	}
	bitmap from_prev_iter;
	bmp = src;
	for( int i = 0; i != iterations; ++i ) {
		bmp.swap( from_prev_iter );
		erode4( bmp, from_prev_iter );
	}
}

void erode8( bitmap &bmp, const bitmap &src, int iterations )
{
	assert( iterations>=1 );
	if( iterations == 1 ) {
		erode8( bmp, src );
		return;
	}
	bitmap from_prev_iter;
	bmp = src;
	for( int i = 0; i != iterations; ++i ) {
		bmp.swap( from_prev_iter );
		erode8( bmp, from_prev_iter );
	}
}

void dilate4( bitmap &bmp, const bitmap &src )
{
	assert(bmp.data() != src.data());
	int w = src.width();
	int h = src.height();
	bmp = src;
	combine( bmp, 1, 0, w, h, src, 0, 0, bit_or() );
	combine( bmp, -1, 0, w, h, src, 0, 0, bit_or() );
	combine( bmp, 0, 1, w, h, src, 0, 0, bit_or() );
	combine( bmp, 0, -1, w, h, src, 0, 0, bit_or() );
}

void dilate8( bitmap &bmp, const bitmap &src )
{
	assert(bmp.data() != src.data());
	int w = src.width();
	int h = src.height();
	bitmap tmp = src;
	combine( tmp,  1,  0, w, h, src, 0, 0, bit_or() );
	combine( tmp, -1,  0, w, h, src, 0, 0, bit_or() );
	bmp = tmp;
	combine( bmp,  0,  1, w, h, tmp, 0, 0, bit_or() );
	combine( bmp,  0, -1, w, h, tmp, 0, 0, bit_or() );
}

void dilate4( bitmap &bmp, const bitmap &src, int iterations )
{
	assert( iterations>=1 );
	if( iterations == 1 ) {
		dilate4( bmp, src );
		return;
	}
	bitmap from_prev_iter;
	bmp = src;
	for( int i = 0; i != iterations; ++i ) {
		bmp.swap( from_prev_iter );
		dilate4( bmp, from_prev_iter );
	}
}

void dilate8( bitmap &bmp, const bitmap &src, int iterations )
{
	assert( iterations>=1 );
	if( iterations == 1 ) {
		dilate8( bmp, src );
		return;
	}
	bitmap from_prev_iter;
	bmp = src;
	for( int i = 0; i != iterations; ++i ) {
		bmp.swap( from_prev_iter );
		dilate8( bmp, from_prev_iter );
	}
}

void open4( bitmap &bmp, const bitmap &src, int iterations )
{
	bitmap tmp;
	erode4( tmp, src, iterations );
	dilate4( bmp, tmp, iterations );
}

void open8( bitmap &bmp, const bitmap &src, int iterations )
{
	bitmap tmp;
	erode8( tmp, src, iterations );
	dilate8( bmp, tmp, iterations );
}

void close4( bitmap &bmp, const bitmap &src, int iterations )
{
	bitmap tmp;
	dilate4( tmp, src, iterations );
	erode4( bmp, tmp, iterations );
}

void close8( bitmap &bmp, const bitmap &src, int iterations )
{
	bitmap tmp;
	dilate8( tmp, src, iterations );
	erode8( bmp, tmp, iterations );
}

}
